import java.awt.*;
import java.util.*;
import javax.swing.*;

public class ProducerAndConsumer  extends JFrame {

   Container  c 	= null;
   JPanel     pn 	= new JPanel( );

   public ProducerAndConsumer () {
	c = getContentPane();
	pn.setBackground( Color.black ); 
	pn.setForeground( Color.black ); 
	c.add( pn, BorderLayout.CENTER );
	setSize(650, 400);
	setVisible( true );
	
  }

   public static void main( String args[] ) {

	ProducerAndConsumer app = new ProducerAndConsumer();

	PCMonitor mtr = new PCMonitor( );
	for ( int i = 1; i <= 3; i ++ )
		( new Thread ( new Producer( i, mtr, app.pn )) ).start();
 
  }
}

class PCMonitor {
   public static int nextItem = 1;
   int count, in, out, item [];

   public PCMonitor( ) {
	count = in = out = 0;
	item = new int[10];
   }

   synchronized public void put( int iLabel ) {
      try {
	while ( count >= item.length ) wait();
	item[in] = iLabel ;
	in = (in + 1) % item.length;
	count++;
	notify();
      } catch (InterruptedException e) { }
   }

   synchronized public int get () { 
      try {
	while ( count == 0 ) wait() ;
	int itm = item[out];
	out = ( out + 1 ) % item.length;
	count --;
        return itm;
      } catch (InterruptedException e) { }
      return -1;
   }
   synchronized public int getNo ( ) {
      int n = nextItem ++;
      return n;
   }
}

class Producer implements Runnable {
  public static Random rdm = new Random( ) ;
  int ID;
  PCMonitor mtr = null;
  JPanel pn = null;
  Graphics g = null;
  int	   lastItem;

  public Producer ( int id, PCMonitor m, JPanel p ) { ID = id; mtr = m; pn = p; g = pn.getGraphics() ; }

  public void run() { 
     while ( true ) {
	simulate( "working", 4, 6 );
	simulate( "puttig", 1, 2 );
	lastItem = mtr.getNo();
	mtr.put( lastItem );
	draw ( String.format( "Producer %d has produced item %d", ID, lastItem )) ;
	simulate( "relaxing", 2, 3 );
     }
  }
  void draw( String s ) {
     int x =20,  y = ID * 30; 
     g.setColor( pn.getBackground() ) ;
     g.fillRect(x, y - 25, 300, 28 );
     g.setColor( Color.white );
     g.drawString( "Producer " + ID + "(" + lastItem  + "): " + s, x, y );
  }
  void simulate( String s, int lb, int ub ) {
     draw( s );
     try {
	Thread.sleep( rdm.nextInt( ub * 1000 - lb * 1000 + 1)  + lb * 1000 );
     } catch ( InterruptedException e ) {  }
   }
}

class Consumer implements Runnable {
  public void run() { }
}
